#include "State.h"

LevelState::LevelState(RenderWindow* window, string level) : State(window, LEVEL) {
    try {
        currentLevel = new Level(level);
    } catch(Exception e) { err.handle(e); }

    stateId   = LEVEL;
    nextState = LEVEL;

    heroHealth = new Healthbar(currentLevel->hero->getMaxHealth(), window, this);

    // TODO: scale ALL IMAGES (from imagemanager?) for current resolution
    for (vector<Character*>::iterator i = currentLevel->characters.begin(); i != currentLevel->characters.end(); i++) {
        (*i)->getSprite().Scale(2, 2);
    }
}

void LevelState::onEvent(Event event) {
    // Close window; exit
    if (event.Type == Event::Closed) {
        window->Close();
    }

    if (event.Type == Event::KeyPressed) {
        switch (event.Key.Code) {
            // Quit
            case Key::Escape:
                nextState = LEVEL_SELECT;
                break;

            // Jump
            case Key::Up:
                currentLevel->hero->jump();
                break;

            // Attack
            case Key::A:
                currentLevel->hero->attack("punch");
                break;

            // TODO: 4 testing....
            case Key::H:
                currentLevel->hero->hit(32);
                break;
        }
    }
}

void LevelState::onHold() {
    const Input& input = window->GetInput();
    
    // Walking
    if (input.IsKeyDown(Key::Left)) {
        currentLevel->hero->walk(LEFT);
    } else if (input.IsKeyDown(Key::Right)) {
        currentLevel->hero->walk(RIGHT);
    }
}

void LevelState::render() {
    // Clear screen
    window->Clear();
    
    if (currentLevel->hero->isAlive()) {
        window->Draw(*currentLevel->background);
        
        // Draw all collidable objects
        for (vector<Sprite*>::iterator i = currentLevel->collidables.begin(); i != currentLevel->collidables.end(); i++) {
            window->Draw(**i);
        }
        
        // Draw all characters
        for (vector<Character*>::iterator i = currentLevel->characters.begin(); i != currentLevel->characters.end(); i++) {
            if ((*i)->isAlive()) {
                window->Draw((*i)->getSprite());
            }
        }

        window->Draw(*currentLevel->foreground);    

        heroHealth->draw(currentLevel->hero->getHealth());
    } else {
        // TODO: ??? fade? idk
        String death("You died :(");
        death.SetColor(sf::Color(200, 0, 0));
        death.SetPosition(WINDOW_WIDTH/3, WINDOW_HEIGHT/3);
        death.SetSize(70);

        window->Draw(death);
    }
    
    // Display framerate
    if (SHOW_FRAMERATE) {
        framerate->SetText(getFramerate());
        window->Draw(*framerate);
    }
    
    // Display the rendered frame on screen
    window->Display();
}

LevelState::~LevelState() {
    delete currentLevel;
    delete heroHealth;
}

LevelState::Healthbar::Healthbar(int maxHealth, RenderWindow* window, LevelState* parent) {
    this->parent    = parent;
    this->window    = window;
    this->maxHealth = maxHealth;

    health = new String();
    
    // Retrieve the characters xml
    TiXmlElement* healthXml = getChildElementbyName("heroHealth", parent->guiXml);
    TiXmlElement* position = healthXml->FirstChildElement("position");
    
    health->SetPosition(Chameleon(position->Attribute("x")),
                        Chameleon(position->Attribute("y")));
    health->SetSize(Chameleon(healthXml->Attribute("size")));
}

void LevelState::Healthbar::setMaxHealth(int newMaxHealth) {
    maxHealth = newMaxHealth;
}

void LevelState::Healthbar::draw(int currentHealth) {
    health->SetText((string)Chameleon(currentHealth) + '/' + (string)Chameleon(maxHealth));

    window->Draw(*health);
}

LevelState::Healthbar::~Healthbar() {
    delete health;
}
